#include <gtest/gtest.h>
#include <filesystem>
#include "../utils/test_utils.h"

using namespace TestUtils;

class BuildTargetsTest : public ::testing::Test {
protected:
    void SetUp() override {
        cleanupBuildOutputs();
        setEnvironmentVariable("BUILD_PROJECT_ROOT", std::filesystem::current_path().parent_path().string());
    }
    
    void TearDown() override {
        unsetEnvironmentVariable("BUILD_PROJECT_ROOT");
        cleanupBuildOutputs();
    }
};

TEST_F(BuildTargetsTest, SpecificTargetBuild) {
    TestScope scope("SpecificTargetBuild");
    
    // 构建特定目标
    std::string command = Commands::BUILD_TARGET + " " + Targets::HELLO_WORLD;
    auto result = executeBuildCommand(command);
    
    // 验证构建成功
    EXPECT_EQ(result.exitCode, 0) << "Target build failed with output: " << result.output;
    EXPECT_TRUE(result.containsOutput("Build completed successfully")) 
        << "Success message not found";
    
    // 验证目标文件生成
    std::string targetPath = Paths::OUT_RELEASE + "/" + Targets::HELLO_WORLD;
    EXPECT_TRUE(fileExists(targetPath)) 
        << "Target executable not found at: " << targetPath;
}

TEST_F(BuildTargetsTest, ExecutableTargetRuntime) {
    TestScope scope("ExecutableTargetRuntime");
    
    // 构建hello_world目标
    std::string buildCommand = Commands::BUILD_TARGET + " " + Targets::HELLO_WORLD;
    auto buildResult = executeBuildCommand(buildCommand);
    ASSERT_EQ(buildResult.exitCode, 0) << "Build failed";
    
    // 运行可执行文件
    std::string targetPath = Paths::OUT_RELEASE + "/" + Targets::HELLO_WORLD;
    ASSERT_TRUE(fileExists(targetPath)) << "Executable not found";
    
    auto runResult = executeBuildCommand(targetPath);
    EXPECT_EQ(runResult.exitCode, 0) << "Executable failed to run";
    EXPECT_TRUE(runResult.containsOutput("Hello")) 
        << "Expected output not found: " << runResult.output;
}

TEST_F(BuildTargetsTest, MultipleTargetsBuild) {
    TestScope scope("MultipleTargetsBuild");
    
    // 构建多个目标
    std::vector<std::string> targets = {
        Targets::HELLO_WORLD,
        Targets::FEATURE_TEST
    };
    
    for (const auto& target : targets) {
        std::string command = Commands::BUILD_TARGET + " " + target;
        auto result = executeBuildCommand(command);
        
        EXPECT_EQ(result.exitCode, 0) 
            << "Target " << target << " build failed: " << result.output;
        EXPECT_TRUE(result.containsOutput("Build completed successfully")) 
            << "Success message not found for target: " << target;
    }
}

TEST_F(BuildTargetsTest, InvalidTargetHandling) {
    TestScope scope("InvalidTargetHandling");
    
    // 尝试构建不存在的目标
    std::string command = Commands::BUILD_TARGET + " invalid_target_name";
    auto result = executeBuildCommand(command);
    
    // 应该失败并给出合理的错误信息
    EXPECT_NE(result.exitCode, 0) << "Invalid target should fail to build";
    // 注意：这里可能需要根据实际的错误处理机制调整验证逻辑
}

TEST_F(BuildTargetsTest, TargetDependencyResolution) {
    TestScope scope("TargetDependencyResolution");
    
    // 构建有依赖关系的目标
    std::string command = Commands::BUILD_TARGET + " calculator_app";
    auto result = executeBuildCommand(command);
    
    EXPECT_EQ(result.exitCode, 0) << "Dependent target build failed: " << result.output;
    
    // 验证依赖解析信息
    EXPECT_TRUE(result.containsOutput("calculator_app -> math")) 
        << "Dependency resolution not shown: " << result.output;
}

TEST_F(BuildTargetsTest, LibraryTargets) {
    TestScope scope("LibraryTargets");
    
    // 测试静态库构建
    auto staticResult = executeBuildCommand(Commands::PYTHON_BUILD + " " + Targets::TEST_STATIC_LIB);
    EXPECT_EQ(staticResult.exitCode, 0) << "Static library build failed: " << staticResult.output;
    
    // 验证静态库文件生成
    std::string staticLibPath = "out/intermediate/lib/test_static_lib/libtest_static_lib.a";
    EXPECT_TRUE(fileExists(staticLibPath)) 
        << "Static library not found at: " << staticLibPath;
    
    // 测试动态库构建
    auto sharedResult = executeBuildCommand(Commands::PYTHON_BUILD + " " + Targets::TEST_SHARED_LIB);
    EXPECT_EQ(sharedResult.exitCode, 0) << "Shared library build failed: " << sharedResult.output;
    
    // 验证动态库文件生成
    std::string sharedLibPath = Paths::OUT_RELEASE + "/libtest_shared_lib.so";
    EXPECT_TRUE(fileExists(sharedLibPath)) 
        << "Shared library not found at: " << sharedLibPath;
}

TEST_F(BuildTargetsTest, HeaderLibraryTargets) {
    TestScope scope("HeaderLibraryTargets");
    
    // 测试头文件库构建
    auto result = executeBuildCommand(Commands::PYTHON_BUILD + " " + Targets::TEST_HEADERS);
    
    EXPECT_EQ(result.exitCode, 0) << "Header library build failed: " << result.output;
    EXPECT_TRUE(result.containsOutput("Build completed successfully")) 
        << "Header library success message not found";
    
    // 验证头文件库标记文件
    std::string headerLibFile = "out/intermediate/headers/test_headers.header_lib";
    EXPECT_TRUE(fileExists(headerLibFile)) 
        << "Header library marker file not found: " << headerLibFile;
}

TEST_F(BuildTargetsTest, ApplicationWithLibraryDependencies) {
    TestScope scope("ApplicationWithLibraryDependencies");
    
    // 构建依赖头文件库的应用程序
    auto result = executeBuildCommand(Commands::PYTHON_BUILD + " " + Targets::TEST_APP);
    
    EXPECT_EQ(result.exitCode, 0) << "Application build failed: " << result.output;
    
    // 验证应用程序文件生成
    std::string appPath = Paths::OUT_RELEASE + "/test_app";
    EXPECT_TRUE(fileExists(appPath)) << "Application not found at: " << appPath;
    
    // 运行应用程序测试
    auto runResult = executeBuildCommand(appPath);
    EXPECT_EQ(runResult.exitCode, 0) << "Application failed to run: " << runResult.output;
    EXPECT_TRUE(runResult.containsOutput("Header library test completed successfully")) 
        << "Expected application output not found: " << runResult.output;
}